#ifndef CARRIAGE_H_INCLUDED
#define CARRIAGE_H_INCLUDED

#include "mhdef.h"
#include <pthread.h>
#include "act_types.h"
#include "yc.h"
#include "sel.h"
#include "crgcam.h"
#include "motor.h"
#include "feedback.h"
#include "cmd.h"

#define GROUP_YC1       0
#define GROUP_YC2       1
#define GROUP_FCAM1     2
#define GROUP_BCAM1     3
#define GROUP_FCAM2     4
#define GROUP_BCAM2     5
#define GROUP_SELF1     6
#define GROUP_SELF2     7
#define GROUP_SELB1     8
#define GROUP_SELB2     9
#define GROUP_SELF3     10
#define GROUP_SELF4     11
#define GROUP_SELB3     12
#define GROUP_SELB4     13
#define GROUP_STITCHF1  14
#define GROUP_STITCHB1  15
#define GROUP_STITCHF2  16
#define GROUP_STITCHB2  17
#define GROUP_SINK      18

/* 该顺序不能改变 */
enum { GROUP_CYCLE = 0, ALL_CYCLE, SINGLE_CYCLE };


#define CYCLE_SINGLE_BIT    (0x01 << SINGLE_CYCLE)
#define CYCLE_GROUP_BIT     (0x01 << GROUP_CYCLE)
#define CYCLE_ALL_BIT       (0x01 << ALL_CYCLE)

typedef enum _TestObject TestObject;
enum _TestObject { TEST_YC = 0, TEST_SEL, TEST_MOTOR, TEST_CAM, TEST_END };

typedef enum _StitchGroup StitchGroup;
enum _StitchGroup { STF12 = 0, STB12, STF34, STB34, ST_ALL };

typedef enum _CamGroup CamGroup;
enum _CamGroup { CAMF1 = 0, CAMB1, CAMF2, CAMB2, CAM_ALL };

typedef enum _RestoreState RestoreState;
enum _RestoreState { RESTORE_NONE = 0, RESTORE_REQUEST, RESTORE_SUCCESS, RESTORE_FAILED };

typedef struct _CARRIAGE CARRIAGE;

struct _CARRIAGE
{
    int handle;                     /* 窗口句柄 */
    short warn;                     /* 报警编码 */
    int error_state;                /* 机头错误状态 */
    pthread_t th_query;
    pthread_mutex_t crg_mutex;
    TestObject test_object;         /* 测试对象 */
    short cycle_flag;
    short reset_all;                /* 复位所有 */
    RestoreState restore;           /* 恢复状态 */
    short exit;
    short carriage_type;            /* 左机头or右机头 */
    short cancel_cycle;             /* 停止循环 */
    MH_UDP *pudp;
    int flush_wnd;

    YC *yc;
    SEL *sel;
    CAM *cam;
    MOTOR *motor;
    FEEDBACK fb;                    /* 机头反馈对象 */
};

CARRIAGE* carriage_new(MH_UDP *pudp, int handle);
int carriage_get_state(CARRIAGE *crg);
void carriage_setting_pos(CARRIAGE *crg, short st, short sink);
void carriage_close(CARRIAGE *crg);
void carriage_updatewindow(CARRIAGE *crg, int show);

int carriage_yc_exec(CARRIAGE *crg, int group, int index);
int carriage_sel_exec(CARRIAGE *crg, int group, int index);
int carriage_cam_exec(CARRIAGE *crg, int group, int index);
int carriage_motor_exec(CARRIAGE *crg, int group, int index);

int carriage_get_warn();
void carriage_request_cancel_cycle(CARRIAGE *crg);
void carriage_cancel_cycle(CARRIAGE *crg);

void carriage_request_cycle(CARRIAGE *crg, int group, int index, int cycle_type, TestObject to);
int carriage_single_cycle(CARRIAGE *crg);
int carriage_group_cycle(CARRIAGE *crg);
int carriage_reset_all_cycle(CARRIAGE *crg);
int carriage_all_cycle(CARRIAGE *crg);

int carriage_check_error(CARRIAGE *crg);

void carriage_reset_all(CARRIAGE *crg);
int carriage_reset_all_cycle(CARRIAGE *crg);
int carriage_reset_yc_cycle(CARRIAGE *crg);
int carriage_reset_cam_cycle(CARRIAGE *crg);
int carriage_reset_sel_cycle(CARRIAGE *crg);
int carriage_reset_stitch(CARRIAGE *crg);
int carriage_reset_cam_motor(CARRIAGE *crg);

int carriage_restore_cycle(CARRIAGE *crg);
int carriage_restore(CARRIAGE *ct);

void carriage_get_yc_state(CARRIAGE *crg, uchar *yc_state);
void carriage_get_cam_state(CARRIAGE *crg, uchar *cam_state);
void carriage_get_sel_state(CARRIAGE *crg, uchar *sel_state);
void carriage_get_motor_pos(CARRIAGE *crg, short *pos, int num);
void carriage_get_sensor_state(CARRIAGE *crg, char *state, int num);

void carriage_set_carriage_type(CARRIAGE *crg, int type);
void carriage_set_sink_enable(CARRIAGE *crg, BOOL sink_enable);

int carriage_get_cycle_flag(CARRIAGE *crg);
int carriage_get_reset_all(CARRIAGE *crg);
int carriage_get_flush_data(CARRIAGE *crg);
void carriage_set_flush_data(CARRIAGE *crg, int state);

int carriage_yc_group_exec(CARRIAGE *crg, int group, uchar state);
int carriage_sel_group_exec(CARRIAGE *crg, int group, uchar state);
int carriage_cam_group_exec(CARRIAGE *crg, int group, uchar state);
int carriage_motor_group_exec(CARRIAGE *crg, int group, uchar state);
#endif // CARRIAGE_H_INCLUDED
